﻿/**
 * @file SocketTest.c
 * @brief test of Socket
 * $Id: SocketTest.cc 13 2011-01-01 11:48:27Z tonyjobmails $
 * $Date: 2011-01-01 11:48:27 +0000 (Sat, 01 Jan 2011) $
 * $Author: tonyjobmails $
 * $Revision: 13 $
 */

#include <vector>
#include <sys/epoll.h>
#include "Socket.h"
#include "SocketTest.h"

void TestSocketClient()
{
	std::vector<struct epoll_event> events;
	
	int epfd = epoll_create(1);

	events.resize(1);

	int sockfd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(sockfd == -1)
	{
		log::_ERROR_LOG("创建socket失败，%s", __PRETTY_FUNCTION__);
		return ;
	}

#ifdef _TOTO_DEBUG
	log::_DEBUG_LOG("创建socket成功，套接口 [%u]", sockfd);
#endif

	/// 地址和端口(网络字节序)
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	addr.sin_port = htons(80);

	if(::connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
	{
		log::_ERROR_LOG("连接失败，%s", __PRETTY_FUNCTION__);
		::close(sockfd);
		return ;
	}

	/// 通信使用的socket
	Socket socket(sockfd);

	if(socket.addEpoll(epfd, EPOLLIN | EPOLLOUT | EPOLLERR, NULL) == -1)
	{
		log::_ERROR_LOG("加入epoll事件错误，%s", __PRETTY_FUNCTION__);
		return ;
	}

	int count = 0;

	while(1)
	{
#ifdef _TOTO_DEBUG
		log::_DEBUG_LOG("进入事件循环，%s", __PRETTY_FUNCTION__);
#endif
		int ret = epoll_wait(epfd, &events[0], 1, 1024);
		if(ret > 0)
		{
			log::_DEBUG_LOG("事件发生，%s", __PRETTY_FUNCTION__);
			size_t pos = 0;
			for(; pos < events.size(); ++pos)
			{
				if(events[pos].events & EPOLLIN)
				{
					log::_DEBUG_LOG("EPOLLIN事件响应，%s", __PRETTY_FUNCTION__);
					socket.recv_buff();
				}
				if(events[pos].events & EPOLLOUT)
				{
					log::_DEBUG_LOG("EPOLLOUT事件响应，%s", __PRETTY_FUNCTION__);
					socket.send_to_buff((const unsigned char *)"1234567890", sizeof("1234567890"));
					socket.send_buff();
				}
				if(events[pos].events & EPOLLERR)
				{
					log::_ERROR_LOG("EPOLLERR事件发生，%s", __PRETTY_FUNCTION__);
				}
			}
		}

		if(++count > 5)
			return;

		::sleep(5);
	}

	socket.delEpoll(epfd, EPOLLIN | EPOLLOUT | EPOLLERR);
}

void TestSocketServer()
{
	std::vector<struct epoll_event> events;

	int epfd = epoll_create(1);

	events.resize(1);

	int sockfd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(sockfd == -1)
	{
		log::_ERROR_LOG("创建socket失败，%s", __PRETTY_FUNCTION__);
		return ;
	}

#ifdef _TOTO_DEBUG
	log::_DEBUG_LOG("创建socket成功");
#endif

	/// 地址和端口(网络字节序)
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	addr.sin_port = htons(80);

	if(::bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
	{
		log::_ERROR_LOG("绑定地址端口失败，%s", __PRETTY_FUNCTION__);
		::close(sockfd);
		return ;
	}

#ifdef _TOTO_DEBUG
	log::_DEBUG_LOG("绑定端口地址成功");
#endif

	if(::listen(sockfd, 5) == -1)
	{
		log::_ERROR_LOG("监听失败，%s", __PRETTY_FUNCTION__);
		::close(sockfd);
	}

#ifdef _TOTO_DEBUG
	log::_DEBUG_LOG("监听客户连接");
#endif

	struct sockaddr_in clientAddr;
	socklen_t len = sizeof(clientAddr);
	int sockclient = ::accept(sockfd, (struct sockaddr *)&clientAddr, &len);
	if(sockclient == -1)
	{
		log::_ERROR_LOG("接收连接失败，%s", __PRETTY_FUNCTION__);
		return ;
	}

#ifdef _TOTO_DEBUG
	log::_DEBUG_LOG("接到连接，接受连接，套接口 [%u]", sockclient);
#endif

	::close(sockfd);

	/// 通信使用的socket
	Socket socket(sockclient);

	if(socket.addEpoll(epfd, EPOLLIN | EPOLLOUT | EPOLLERR, NULL) == -1)
	{
		log::_ERROR_LOG("加入epoll事件错误，%s", __PRETTY_FUNCTION__);
		return ;
	}

	int count = 0;

	while(1)
	{
#ifdef _TOTO_DEBUG
		log::_DEBUG_LOG("进入事件循环，%s", __PRETTY_FUNCTION__);
#endif
		int ret = epoll_wait(epfd, &events[0], 1, 1024);
		if(ret > 0)
		{
			log::_DEBUG_LOG("事件发生，%s", __PRETTY_FUNCTION__);
			size_t pos = 0;
			for(; pos < events.size(); ++pos)
			{
				if(events[pos].events & EPOLLIN)
				{
					log::_DEBUG_LOG("EPOLLIN事件响应，%s", __PRETTY_FUNCTION__);
					socket.recv_buff();
				}
				if(events[pos].events & EPOLLOUT)
				{
					log::_DEBUG_LOG("EPOLLOUT事件响应，%s", __PRETTY_FUNCTION__);
					socket.send_to_buff((const unsigned char *)"22222222", sizeof("22222222"));
					socket.send_buff();
				}
				if(events[pos].events & EPOLLERR)
				{
					log::_ERROR_LOG("EPOLLERR事件发生，%s", __PRETTY_FUNCTION__);
				}
			}

			if(++count > 5)
				return;
		}
		::sleep(5);
	}

	socket.delEpoll(epfd, EPOLLIN | EPOLLOUT | EPOLLERR);
}
